package com.sundata.practice;

import akka.actor.typed.ActorRef;
import akka.actor.typed.ActorSystem;
import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.AbstractBehavior;
import akka.actor.typed.javadsl.ActorContext;
import akka.actor.typed.javadsl.Behaviors;
import akka.actor.typed.javadsl.Receive;

// 定义一个 Actor 类，PrintMyActorRefActor，用于打印 ActorRef
class PrintMyActorRefActor extends AbstractBehavior<String> {

    // 工厂方法，用于创建 PrintMyActorRefActor 的实例
    static Behavior<String> create() {
        return Behaviors.setup(PrintMyActorRefActor::new);
    }

    // 构造函数，初始化 Actor 上下文
    private PrintMyActorRefActor(ActorContext<String> context) {
        super(context);
    }

    // 定义消息处理逻辑
    @Override
    public Receive<String> createReceive() {
        return newReceiveBuilder().onMessageEquals("printit", this::printIt).build();
    }

    // 处理 "printit" 消息的方法，创建并打印一个新的 ActorRef
    private Behavior<String> printIt() {
        ActorRef<String> secondRef = getContext().spawn(Behaviors.empty(), "second-actor");
        System.out.println("Second: " + secondRef);
        return this; // 返回当前行为
    }
}

// 定义另一个 Actor 类，Main，用于启动并发送消息给 PrintMyActorRefActor
class Main extends AbstractBehavior<String> {

    // 工厂方法，用于创建 Main Actor 的实例
    static Behavior<String> create() {
        return Behaviors.setup(Main::new);
    }

    // 构造函数，初始化 Actor 上下文
    private Main(ActorContext<String> context) {
        super(context);
    }

    // 定义消息处理逻辑
    @Override
    public Receive<String> createReceive() {
        return newReceiveBuilder().onMessageEquals("start", this::start).build();
    }

    // 处理 "start" 消息的方法，创建 PrintMyActorRefActor 并发送消息
    private Behavior<String> start() {
        ActorRef<String> firstRef = getContext().spawn(PrintMyActorRefActor.create(), "first-actor");

        System.out.println("First: " + firstRef);
        firstRef.tell("printit"); // 向 firstRef 发送 "printit" 消息
        return Behaviors.same(); // 保持当前行为不变
    }
}

// 主类，启动 Actor 系统并发送初始消息
public class ActorHierarchyExperiments {
    public static void main(String[] args) {
        ActorRef<String> testSystem = ActorSystem.create(Main.create(), "testSystem");
        testSystem.tell("start"); // 向系统发送 "start" 消息
    }
}